package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.*;
import com.zzyl.common.core.redis.RedisCache;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.framework.aspectj.LogAspect;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.vo.DeviceDetailVo;
import com.zzyl.nursing.vo.DevicePropertiesDataVo;
import com.zzyl.nursing.vo.ProductVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2025-08-26
 */
@Service
@Slf4j
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {


    @Autowired
    private RedisCache redisCache;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private IoTDAClient client;
    @Autowired
    private LogAspect logAspect;


    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public Device selectDeviceById(Long id) {
        return getById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param device 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<Device> selectDeviceList(Device device) {
        return deviceMapper.selectDeviceList(device);
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param device 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertDevice(Device device) {
        return save(device) ? 1 : 0;
    }

    /**
     * 修改【请填写功能名称】
     *
     * @param device 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateDevice(Device device) {
        return updateById(device) ? 1 : 0;
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteDeviceByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteDeviceById(Long id) {
        return removeById(id) ? 1 : 0;
    }


    //同步产品
    @Override
    public void syncProductList() {
        ListProductsResponse listProductsResponse = client.listProducts(new ListProductsRequest());
        log.info("华为云iot平台返回数据:{}", listProductsResponse);
        List<ProductSummary> products = listProductsResponse.getProducts();
        List<ProductVo> productVos = products.stream()
                .map(p -> new ProductVo(p.getProductId(), p.getName()))
                .collect(Collectors.toList());

        redisCache.setCacheObject("IOT_ALL_PRODUCTS", productVos);
    }

    @Override
    public List<ProductVo> listAll() {
        return redisCache.getCacheObject("IOT_ALL_PRODUCTS");
    }

    @Override
    public void addProduct(DeviceDto deviceDto) {
        //业务逻辑
        //。先判断设备的名称和标识是否重复 重复则无法注册
        LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Device::getDeviceName, deviceDto.getDeviceName());
        wrapper.or().eq(Device::getNodeId, deviceDto.getNodeId());
        long count = super.count(wrapper);
        if (count > 0) {
            throw new BaseException("设备名称或设备标识码重复");
        }
        //判断同一位置是否绑定了相同的产品
        LambdaQueryWrapper<Device> wrapper1 = new LambdaQueryWrapper<>();
        //判断
        wrapper1.eq(Device::getProductKey, deviceDto.getProductKey())
                .eq(Device::getLocationType, deviceDto.getLocationType())
                .eq(Device::getPhysicalLocationType, deviceDto.getPhysicalLocationType())
                .eq(Device::getBindingLocation, deviceDto.getBindingLocation());
        long count1 = super.count(wrapper1);
        if (count1 > 0) {
            throw new BaseException("该位置已经绑定了产品，请重新选择");
        }
        //注册进华为云iot
        AddDeviceRequest request = new AddDeviceRequest();
        AddDevice body = new AddDevice();
        body.withProductId(deviceDto.getProductKey());
        body.withDeviceName(deviceDto.getDeviceName());
        body.withNodeId(deviceDto.getNodeId());
        request.withBody(body);
        AuthInfo authInfo = new AuthInfo();
        //秘钥
        String secret = UUID.randomUUID().toString().replaceAll("-", "");
        authInfo.withSecret(secret);
        body.setAuthInfo(authInfo);
        AddDeviceResponse response = client.addDevice(request);

        //插入设备数据到数据库
        Device device = new Device();
        BeanUtils.copyProperties(deviceDto, device);
        device.setIotId(response.getDeviceId());
        device.setSecret(secret);
        super.save(device);

    }

    @Override
    public DeviceDetailVo queryDeviceDetail(String iotId) {
        LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Device::getIotId, iotId);
        Device device = super.getOne(wrapper);
        if (device == null) {
            throw new BaseException("设备不存在");
        }
        DeviceDetailVo deviceDetailVo = new DeviceDetailVo();
        BeanUtils.copyProperties(device, deviceDetailVo);
        //设置创建时间
        deviceDetailVo.setCreateTime(device.getCreateTime());
        //获取iot平台上的设备详细信息
        ShowDeviceRequest request = new ShowDeviceRequest();
        request.setDeviceId(iotId);
        ShowDeviceResponse response = client.showDevice(request);
        //设置状态
        deviceDetailVo.setDeviceStatus(response.getStatus());

        //激活时间
        String activeTimeStr = response.getActiveTime();
        //注意：有可能没有激活
        if (StringUtils.isNotEmpty(activeTimeStr)) {
            LocalDateTime activeTime = LocalDateTimeUtil.parse(activeTimeStr, DatePattern.UTC_MS_PATTERN);
            //时区转换
            activeTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC)).
                    withZoneSameInstant(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
            deviceDetailVo.setActiveTime(activeTime);
        }
        return deviceDetailVo;

    }

    @Override
    public List<DevicePropertiesDataVo> queryServiceProperties(String iotId) {
        ShowDeviceShadowRequest showDeviceShadowRequest = new ShowDeviceShadowRequest();
        showDeviceShadowRequest.setDeviceId(iotId);
        ShowDeviceShadowResponse response = client.showDeviceShadow(showDeviceShadowRequest);
        log.info("获取设备属性值返回:{}", response);
        if (CollectionUtils.isEmpty(response.getShadow())) {
            return new ArrayList<>();
        }
        Object properties = response.getShadow().get(0).getReported().getProperties();
        String eventTimeStr = response.getShadow().get(0).getReported().getEventTime();
        //进行日期转换
        LocalDateTime localDateTime = LocalDateTimeUtil.parse(eventTimeStr, "yyyyMMdd'T'HHmmss'Z'");
        LocalDateTime eventTime = localDateTime.atZone(ZoneId.from(ZoneOffset.UTC))
                .withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
                .toLocalDateTime();
        ArrayList<DevicePropertiesDataVo> vo = new ArrayList<>();
        JSONObject jsonObject = JSONUtil.parseObj(properties);
        jsonObject.forEach((key, value) -> {
            DevicePropertiesDataVo dataVo = new DevicePropertiesDataVo();
            dataVo.setFunctionId(key);
            dataVo.setEventTime(eventTime);
            dataVo.setValue(value);
            vo.add(dataVo);
        });

        return vo;
    }

    @Override
    public void removeDevice(String iotId) {
        ShowDeviceRequest showRequest = new ShowDeviceRequest();
        showRequest.setDeviceId(iotId);
        ShowDeviceResponse showResponse = client.showDevice(showRequest);
        String deviceStatus = showResponse.getStatus();
        if (deviceStatus.equals("ONLINE")) {
            throw new BaseException("设备在线，请先下线设备");
        }
        DeleteDeviceRequest request = new DeleteDeviceRequest();
        request.setDeviceId(iotId);
        try {
            DeleteDeviceResponse response = client.deleteDevice(request);
            log.info("华为云设备删除成功，设备ID: {}", iotId);
        } catch (Exception e) {
            log.error("华为云设备删除失败，设备ID: {}", iotId, e);
            throw new BaseException("删除云端设备失败: " + e.getMessage());
        }
        LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Device::getIotId, iotId);
        super.remove(wrapper);

    }
}
